module Tomahawk
  class ConfigParser
    attr_accessor :result
    def initialize(config_string)
      @config_string = config_string.to_s.strip
      @result = []
    end

    def call
      @config_lines = @config_string.split("\n")
      parse
    end

    private

    def parse

      directive_groups = [Tomahawk::DirectiveGroups::HTTPd.new]

      @config_lines.grep(/^\s*[^#]/).each do |line|

        is_end_tag?(line) do
          directive_groups.pop
        end

        is_start_tag?(line) do |group_name, group_parameters|
          group = Tomahawk::DirectiveGroups.DirectiveGroup(group_name).new(group_parameters)
          directive_groups.last.groups << group
          directive_groups.push(group)
        end

        is_directive?(line) do |directive_name, directive_value|
          directive_groups.last.directives[directive_name] = directive_value
        end
      end

      @result = directive_groups.first
    end

    def is_end_tag?(line, &block)
      if line[/<\/.+?>/]
        yield if block
        return true
      end

      false
    end

    def is_start_tag?(line, &block)
      if line[/<\s*([^\/\s]+)(.*?)>/]
        yield $1.strip, $2.strip if block
        return true
      end

      false
    end

    def is_directive?(line, &block)
      if line[/^\s*([^#<\s]+)(.+)$/]

        if block
          directive_value = $2.strip if $2
          directive_name = $1.scan(/[A-Z][^A-Z\s]*/)
                            .map(&:downcase)
                            .join('_')

          yield(directive_name, directive_value)
        end
        return true
      end

      false
    end
  end
end
